home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / util / gnu / gnu_oleo_1_2_2.lha / oleo-1.2.2 / eval.c < prev    next >
C/C++ Source or Header  |  1993-03-03  |  35KB  |  1,791 lines

  1. /*    Copyright (C) 1990, 1992, 1993 Free Software Foundation, Inc.
  2.  
  3. This file is part of Oleo, the GNU Spreadsheet.
  4.  
  5. Oleo is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. Oleo is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with Oleo; see the file COPYING.  If not, write to
  17. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include <math.h>
  20. #include <ctype.h>
  21. #include <stdio.h>
  22.  
  23. #ifdef __TURBOC__
  24. #define SMALLEVAL
  25. #endif
  26.  
  27. #include "funcdef.h"
  28.  
  29. #if defined(HAVE_RINT)
  30. #ifdef __STDC__
  31. extern double rint (double);
  32. extern long random (void);
  33. #else
  34. extern double rint ();
  35. extern long random ();
  36. #endif
  37. #else
  38. #define rint(x) (((x)<0) ? ceil((x)-.5) : floor((x)+.5))
  39. #endif
  40.  
  41. #define obstack_chunk_alloc ck_malloc
  42. #define obstack_chunk_free free
  43. #include "obstack.h"
  44.  
  45. #include "sysdef.h"
  46. #include "global.h"
  47. #include "cell.h"
  48. #include "eval.h"
  49. #include "errors.h"
  50.  
  51.  
  52. extern int n_usr_funs;
  53.  
  54.  
  55.  
  56.  
  57. double to_int ();
  58. static int deal_area ();
  59. static void add_int ();
  60. static void add_flt ();
  61. #ifndef __TURBOC__
  62. RETSIGTYPE math_sig ();
  63. #endif
  64.  
  65. #ifdef __STDC__
  66. int fls (long);
  67. #else
  68. int fls ();
  69. #endif
  70. #ifdef SMALLEVAL
  71. int __to_flt (struct value *);
  72. int __to_int (struct value *);
  73. int __to_num (struct value *);
  74. int __to_str (struct value *);
  75. int __to_bol (struct value *);
  76. int __to_rng (struct value *);
  77. #endif
  78.  
  79.  
  80.  
  81. struct value
  82.   {
  83.     int type;
  84.     union vals x;
  85.   };
  86.  
  87. #define Float    x.c_d
  88. #define String    x.c_s
  89. #define Int    x.c_l
  90. #define Value    x.c_i
  91. #define Rng    x.c_r
  92.  
  93. #define PI (3.14159265358979326848)
  94.  
  95. static struct value *stack;
  96. static int stackmax;
  97. static int curstack;
  98.  
  99. unsigned short current_cycle;
  100.  
  101. CELLREF cur_row;
  102. CELLREF cur_col;
  103.  
  104. static double exp10_arr[] =
  105. {
  106.   1E0, 1E1, 1E2, 1E3, 1E4,
  107.   1E5, 1E6, 1E7, 1E8, 1E9,
  108.   1E10, 1E11, 1E12, 1E13, 1E14,
  109.   1E15, 1E16, 1E17, 1E18, 1E19,
  110.   1E20, 1E21, 1E22, 1E23, 1E24,
  111.   1E25, 1E26, 1E27, 1E28, 1E29
  112. };
  113.  
  114. /* Various math conversions with error checking */
  115. #define I_ADD(i1,i2) {    itmp=(i1)+(i2);                    \
  116.             if((i1>0)==(i2>0) && (itmp>0)!=(i1>0)) {    \
  117.                 p->Float=(double)(i1)+(double)(i2);    \
  118.                 p->type=TYP_FLT;            \
  119.             } else                        \
  120.                 p->Int=itmp;    }
  121.  
  122. #define I_SUB(i1,i2) {    itmp=(i1)-(i2);                    \
  123.             if(((i1)<0)==((i2)>0) && ((itmp)>0)!=((i2)<0)) {\
  124.                 p->Float=(double)(i1)-(double)(i2);    \
  125.                 p->type=TYP_FLT;            \
  126.             } else                        \
  127.                 p->Int=itmp;    }
  128.  
  129. #define I_DIV(i1,i2) {    ftmp=(double)(i1)/(double)(i2);            \
  130.             /* ... */;                    \
  131.             p->Float=ftmp;                    \
  132.             p->type=TYP_FLT;    }
  133.  
  134. #define I_MOD(i1,i2) {itmp=(i1)%(i2);/* ... */;p->Int=itmp;}
  135.  
  136. #define I_MUL(i1,i2) {    if(fls(i1)+fls(i2)>32) {            \
  137.                 p->Float=(double)(i1)*(double)(i2);    \
  138.                 p->type=TYP_FLT;            \
  139.             } else                        \
  140.                 p->Int=(i1)*(i2);    }
  141.  
  142. #define F_ADD(f1,f2) {    ftmp=(f1)+(f2);/* ... */;p->Float=ftmp;    }
  143.  
  144. #define F_SUB(f1,f2) {    ftmp=(f1)-(f2);/* ... */;p->Float=ftmp;}
  145.  
  146. #define F_DIV(f1,f2) {    ftmp=(f1)/(f2);/* ... */;p->Float=ftmp;}
  147.  
  148. #define F_MOD(f1,f2) {    itmp=(long)(f1)%(long)(f2);/* ... */;p->Int=itmp;p->type=TYP_INT;}
  149.  
  150. #define F_MUL(f1,f2) {    ftmp=(f1)*(f2);/* ... */;p->Float=ftmp;}
  151.  
  152. double ftmp;
  153. long itmp;
  154. int overflow;
  155.  
  156. /* You may ask:  Why not jsut put the value in stack[0] and goto break_out
  157.    The answer is that ERROR is a valid input type for several operators, so
  158.    we want to work if we're feeding an error into one of these operators. . .
  159.  */
  160. #define ERROR(cause)        \
  161.     {            \
  162.         p->type=TYP_ERR;\
  163.         p->Value=cause; \
  164.         goto next_byte; \
  165.     }
  166.  
  167. #ifdef SMALLEVAL
  168.  
  169. #define TO_FLT(val)            \
  170.     if((tmp=__to_flt(val))!=0)    \
  171.         ERROR(tmp);
  172.  
  173. #define TO_INT(val)            \
  174.     if((tmp=__to_int(val))!=0)    \
  175.         ERROR(tmp);
  176.  
  177. #define TO_NUM(val)            \
  178.     if((tmp=__to_num(val))!=0)    \
  179.         ERROR(tmp);
  180.  
  181. #define TO_STR(val)            \
  182.     if((tmp=__to_str(val))!=0)    \
  183.         ERROR(tmp);
  184.  
  185. #define TO_BOL(val)            \
  186.     if((tmp=__to_bol(val))!=0)    \
  187.         ERROR(tmp);
  188.  
  189. #define TO_RNG(val)            \
  190.     if((tmp=__to_rng(val))!=0)    \
  191.         ERROR(tmp);
  192.  
  193. #else
  194. #define TO_FLT(val)    \
  195.     if((val)->type==TYP_FLT) \
  196.         ; \
  197.     else if((val)->type==TYP_INT) { \
  198.         (val)->type=TYP_FLT; \
  199.         (val)->Float=(double)(val)->Int; \
  200.     } else if((val)->type==TYP_STR) { \
  201.         (val)->type=TYP_FLT; \
  202.         strptr=(val)->String; \
  203.         (val)->Float=astof(&strptr); \
  204.         if(*strptr) \
  205.             ERROR(NON_NUMBER); \
  206.     } else if((val)->type==TYP_ERR) {\
  207.         ERROR((val)->Value); \
  208.     } else if((val)->type==0) { \
  209.         (val)->type=TYP_FLT; \
  210.         (val)->Float=0.0; \
  211.     } else \
  212.         ERROR(NON_NUMBER);
  213.  
  214. #define TO_INT(val)    \
  215.     if((val)->type==TYP_INT) \
  216.         ; \
  217.     else if((val)->type==TYP_FLT) { \
  218.         (val)->type=TYP_INT; \
  219.         (val)->Int=(long)(val)->Float; \
  220.     } else if((val)->type==TYP_STR) { \
  221.         (val)->type=TYP_INT; \
  222.         strptr=(val)->String; \
  223.         (val)->Int=astol(&strptr); \
  224.         if(*strptr) \
  225.             ERROR(NON_NUMBER); \
  226.     } else if((val)->type==TYP_ERR) {\
  227.         ERROR((val)->Value); \
  228.     } else if((val)->type==0) { \
  229.         (val)->type=TYP_INT; \
  230.         (val)->Int=0; \
  231.     } else \
  232.         ERROR(NON_NUMBER);
  233.  
  234. #define TO_NUM(val)    \
  235.     if((val)->type==TYP_INT || (val)->type==TYP_FLT) \
  236.         ; \
  237.     else if((val)->type==TYP_STR) { \
  238.         (val)->type=TYP_FLT; \
  239.         strptr=(val)->String; \
  240.         (val)->Float=astof(&strptr); \
  241.         if(*strptr) \
  242.             ERROR(NON_NUMBER); \
  243.     } else if((val)->type==TYP_ERR) {\
  244.         ERROR((val)->Value); \
  245.     } else if((val)->type==0) { \
  246.         (val)->type=TYP_INT; \
  247.         (val)->Int=0; \
  248.     } else \
  249.         ERROR(NON_NUMBER);
  250.  
  251. #define TO_STR(val)    \
  252.     if((val)->type==TYP_STR)    \
  253.         ;    \
  254.     else if((val)->type==TYP_INT) {    \
  255.         char *s;    \
  256.         (val)->type=TYP_STR;    \
  257.         s=obstack_alloc(&tmp_mem,30); \
  258.         sprintf(s,"%ld",(val)->Int); \
  259.         (val)->String=s;    \
  260.     } else if((val)->type==TYP_FLT) {        \
  261.         char *s;                \
  262.         s=flt_to_str((val)->Float);        \
  263.         (void)obstack_grow(&tmp_mem,s,strlen(s)+1); \
  264.         (val)->String=obstack_finish(&tmp_mem);    \
  265.         (val)->type=TYP_STR;            \
  266.     } else if((val)->type==TYP_ERR) {        \
  267.         ERROR((val)->Value);    \
  268.     } else if((val)->type==0) {    \
  269.         (val)->type=TYP_STR;    \
  270.         (val)->String=obstack_alloc(&tmp_mem,1); \
  271.         (val)->String[0]='\0'; \
  272.     } else \
  273.         ERROR(NON_STRING);
  274.  
  275. #define TO_BOL(val)    \
  276.     if((val)->type==TYP_BOL)    \
  277.         ;    \
  278.     else if((val)->type==TYP_ERR) {    \
  279.         ERROR((val)->Value);    \
  280.     } else    \
  281.         ERROR(NON_BOOL);
  282.  
  283.  
  284. #define TO_RNG(val) \
  285.     if((val)->type==TYP_RNG) \
  286.         ; \
  287.     else if((val)->type==TYP_ERR) {\
  288.         ERROR((val)->Value); \
  289.     } else \
  290.         ERROR(NON_RANGE);
  291.  
  292. #endif
  293.  
  294. #define TO_ANY(val) \
  295.     if((val)->type==TYP_RNG) \
  296.         ERROR(BAD_INPUT); \
  297.  
  298. #define PUSH_ANY(cp)                \
  299.     if(!cp || !GET_TYP(cp)) {        \
  300.         p->type=0;            \
  301.         p->Int=0;            \
  302.     } else {                \
  303.         p->type=GET_TYP(cp);        \
  304.         p->x=cp->c_z;            \
  305.     }
  306.  
  307. void
  308. init_eval ()
  309. {
  310.   stack = (struct value *) ck_malloc (20 * sizeof (struct value));
  311.   stackmax = 20;
  312.   curstack = 0;
  313.   current_cycle++;
  314. #ifndef __TURBOC__
  315.   (void) signal (SIGFPE, math_sig);
  316. #endif
  317. }
  318.  
  319. /* This huge function takes a byte-compiled expression and executes it. */
  320. struct value *
  321. eval_expression (expr)
  322.      unsigned char *expr;
  323. {
  324.   unsigned char byte;
  325.   unsigned numarg;
  326.   unsigned jumpto;
  327.   struct function *f;
  328.   struct value *p;
  329.   char *strptr;
  330.   int tmp;
  331.  
  332.   CELLREF lrow, hrow, crow;
  333.   CELLREF lcol, hcol, ccol;
  334.  
  335.   struct cell *cell_ptr;
  336.  
  337.   if (!expr)
  338.     return 0;
  339. #ifdef TEST
  340.   jumpto = 0;
  341.   numarg = 0;
  342.   p = 0;
  343. #endif
  344.   curstack = 0;
  345.   while ((byte = *expr++) != ENDCOMP)
  346.     {
  347.       if (byte < USR1)
  348.     f = &the_funs[byte];
  349.       else if (byte < SKIP)
  350.     {
  351. #ifdef TEST
  352.       if (byte - USR1 >= n_usr_funs)
  353.         panic ("Only have %d usr-function slots, but found byte for slot %d", n_usr_funs, 1 + byte - USR1);
  354. #endif
  355.       tmp = *expr++;
  356.       f = &usr_funs[byte - USR1][tmp];
  357.     }
  358.       else
  359.     f = &skip_funs[byte - SKIP];
  360.  
  361.       if (f->fn_argn & X_J)
  362.     jumpto = *expr++;
  363.       else if (f->fn_argn & X_JL)
  364.     {
  365.       jumpto = expr[0] + ((unsigned) (expr[1]) << 8);
  366.       expr += 2;
  367.     }
  368.  
  369.       switch (f->fn_argn & X_ARGS)
  370.     {
  371.       /* A0 is special, since it makes the stack grow, while
  372.                all the others make the stack the same size or
  373.                less. . . */
  374.     case X_A0:
  375.       numarg = 0;
  376.       if (curstack == stackmax)
  377.         {
  378.           stackmax *= 2;
  379.           stack = (struct value *) ck_realloc (stack, sizeof (struct value) * stackmax);
  380.         }
  381.       p = &stack[curstack];
  382.       curstack++;
  383.       break;
  384.  
  385.     case X_A1:
  386.       numarg = 1;
  387.       break;
  388.  
  389.     case X_A2:
  390.       numarg = 2;
  391.       break;
  392.     case X_A3:
  393.       numarg = 3;
  394.       break;
  395.     case X_A4:
  396.       numarg = 4;
  397.       break;
  398.     case X_AN:
  399.       numarg = *expr++;
  400.       break;
  401. #ifdef TEST
  402.     default:
  403.       panic ("Unknown arg_num %d", f->fn_argn);
  404.       numarg = 0;
  405.       p = 0;
  406. #endif
  407.     }
  408.       if (numarg > 0)
  409.     {
  410.       int xt;
  411.  
  412. #ifdef TEST
  413.       if (curstack < numarg)
  414.         panic ("Only %u values on stack, not %u", curstack, numarg);
  415. #endif
  416.       p = &stack[curstack - numarg];
  417.       curstack -= (numarg - 1);
  418.       for (xt = 0; xt < numarg; xt++)
  419.         {
  420.           switch (f->fn_argt[xt <= 3 ? xt : 3])
  421.         {
  422.           /* A is for anything */
  423.           /* Any non-range value */
  424.         case 'A':
  425.           TO_ANY (p + xt);
  426.           break;
  427.           /* B is for boolean */
  428.         case 'B':
  429.           TO_BOL (p + xt);
  430.           break;
  431.           /* D is for Don't check */
  432.         case 'D':
  433.           break;
  434.           /* E is for Everything */
  435.         case 'E':
  436.           break;
  437.           /* F is for Float */
  438.         case 'F':
  439.           TO_FLT (p + xt);
  440.           break;
  441.           /* I is for Int */
  442.         case 'I':
  443.           TO_INT (p + xt);
  444.           break;
  445.           /* N is for Number (int or float) */
  446.         case 'N':
  447.           TO_NUM (p + xt);
  448.           break;
  449.           /* R is for Range */
  450.         case 'R':
  451.           TO_RNG (p + xt);
  452.           break;
  453.           /* S is for String */
  454.         case 'S':
  455.           TO_STR (p + xt);
  456.           break;
  457. #ifdef TEST
  458.         default:
  459.           io_error_msg ("YIKE!  Unknown argtype for Fun %u  arg #%u", byte, xt);
  460.           break;
  461. #endif
  462.         }
  463.         }
  464.     }
  465.  
  466.       switch (byte)
  467.     {
  468.     case IF_L:
  469.     case F_IF_L:
  470.     case IF:
  471.     case F_IF:
  472.       if (p->type != TYP_BOL)
  473.         {
  474.           if (p->type != TYP_ERR)
  475.         {
  476.           p->type = TYP_ERR;
  477.           p->Value = NON_BOOL;
  478.         }
  479.           expr += jumpto;
  480.           if (expr[-2] != SKIP)
  481.         jumpto = expr[-1] + (((unsigned) expr[-2]) << 8);
  482.           else
  483.         jumpto = expr[-1];
  484.           expr += jumpto;    /* Skip both branches of the if */
  485.  
  486.         }
  487.       else if (p->Value == 0)
  488.         {
  489.           expr += jumpto;
  490.           --curstack;
  491.         }
  492.       else
  493.         --curstack;
  494.       break;
  495.  
  496.     case SKIP_L:
  497.     case SKIP:
  498.       --curstack;
  499.       expr += jumpto;
  500.       break;
  501.  
  502.     case AND_L:
  503.     case AND:
  504.       if (p->type == TYP_ERR)
  505.         expr += jumpto;
  506.       else if (p->type != TYP_BOL)
  507.         {
  508.           p->type = TYP_ERR;
  509.           p->Value = NON_BOOL;
  510.           expr += jumpto;
  511.         }
  512.       else if (p->Value == 0)
  513.         expr += jumpto;
  514.       else
  515.         --curstack;
  516.       break;
  517.  
  518.     case OR_L:
  519.     case OR:
  520.       if (p->type == TYP_ERR)
  521.         expr += jumpto;
  522.       else if (p->type != TYP_BOL)
  523.         {
  524.           p->type = TYP_ERR;
  525.           p->Value = NON_BOOL;
  526.           expr += jumpto;
  527.         }
  528.       else if (p->Value)
  529.         expr += jumpto;
  530.       else
  531.         --curstack;
  532.       break;
  533.  
  534.     case CONST_FLT:
  535.       p->type = TYP_FLT;
  536.       bcopy ((VOIDSTAR) expr, (VOIDSTAR) (&(p->Float)), sizeof (double));
  537.       expr += sizeof (double);
  538.       break;
  539.  
  540.     case CONST_INT:
  541.       p->type = TYP_INT;
  542.       bcopy ((VOIDSTAR) expr, (VOIDSTAR) (&(p->Int)), sizeof (long));
  543.       expr += sizeof (long);
  544.       break;
  545.  
  546.     case CONST_STR:
  547.     case CONST_STR_L:
  548.       p->type = TYP_STR;
  549.       p->String = (char *) expr + jumpto;
  550.       break;
  551.  
  552.     case CONST_ERR:
  553.       p->type = TYP_ERR;
  554.       p->Value = *expr++;
  555.       /* expr+=sizeof(char *); */
  556.       break;
  557.  
  558.     case CONST_INF:
  559.     case CONST_NINF:
  560.     case CONST_NAN:
  561.       p->type = TYP_FLT;
  562.       p->Float = (byte == CONST_INF) ? __plinf : ((byte == CONST_NINF) ? __neinf : __nan);
  563.       break;
  564.  
  565.     case VAR:
  566.       {
  567.         struct var *varp;
  568.  
  569.         bcopy ((VOIDSTAR) expr, (VOIDSTAR) (&varp), sizeof (struct var *));
  570.         expr += sizeof (struct var *);
  571.         switch (varp->var_flags)
  572.           {
  573.           case VAR_UNDEF:
  574.         p->type = TYP_ERR;
  575.         p->Value = BAD_NAME;
  576.         break;
  577.  
  578.           case VAR_CELL:
  579.         cell_ptr = find_cell (varp->v_rng.lr, varp->v_rng.lc);
  580.         PUSH_ANY (cell_ptr);
  581.         break;
  582.  
  583.           case VAR_RANGE:
  584.         if (varp->v_rng.lr == varp->v_rng.hr && varp->v_rng.lc == varp->v_rng.hc)
  585.           {
  586.             cell_ptr = find_cell (varp->v_rng.lr, varp->v_rng.lc);
  587.             PUSH_ANY (cell_ptr);
  588.           }
  589.         else
  590.           {
  591.             p->type = TYP_RNG;
  592.             p->Rng = varp->v_rng;
  593.           }
  594.         break;
  595. #ifdef TEST
  596.           default:
  597.         panic ("Unknown var type %d", varp->var_flags);
  598. #endif
  599.           }
  600.       }
  601.       break;
  602.  
  603.       /* Cell refs */
  604.     case R_CELL:
  605.     case R_CELL | COLREL:
  606.     case R_CELL | ROWREL:
  607.     case R_CELL | ROWREL | COLREL:
  608.       {
  609.         CELLREF torow, tocol;
  610.  
  611.         torow = GET_ROW (expr);
  612.         tocol = GET_COL (expr);
  613.         expr += EXP_ADD;
  614. #ifdef DONTDEF
  615.         if (byte & ROWREL)
  616.           torow = (short) torow + cur_row;
  617.         if (byte & COLREL)
  618.           tocol = (short) tocol + cur_col;
  619. #endif
  620. #ifdef DONTDEF
  621.         if (torow < MIN_ROW || torow > MAX_ROW || tocol < MIN_COL || tocol > MAX_COL)
  622.           {
  623.         p->type = TYP_ERR;
  624.         p->Value = OUT_OF_RANGE;
  625.           }
  626.         else
  627.           {
  628. #endif
  629.         cell_ptr = find_cell ((CELLREF) torow, (CELLREF) tocol);
  630.         PUSH_ANY (cell_ptr);
  631. #ifdef DONTDEF
  632.           }
  633. #endif
  634.       }
  635.       break;
  636.  
  637.     case RANGE:
  638.     case RANGE | LRREL:
  639.     case RANGE | LRREL | LCREL:
  640.     case RANGE | LRREL | LCREL | HCREL:
  641.     case RANGE | LRREL | HCREL:
  642.     case RANGE | LRREL | HRREL:
  643.     case RANGE | LRREL | HRREL | LCREL:
  644.     case RANGE | LRREL | HRREL | LCREL | HCREL:
  645.     case RANGE | LRREL | HRREL | HCREL:
  646.     case RANGE | HRREL:
  647.     case RANGE | HRREL | LCREL:
  648.     case RANGE | HRREL | LCREL | HCREL:
  649.     case RANGE | HRREL | HCREL:
  650.     case RANGE | LCREL:
  651.     case RANGE | LCREL | HCREL:
  652.     case RANGE | HCREL:
  653.       p->type = TYP_RNG;
  654.       GET_RNG (expr, &(p->Rng));
  655.       expr += EXP_ADD_RNG;
  656.       break;
  657.  
  658.     case F_TRUE:
  659.     case F_FALSE:
  660.       p->type = TYP_BOL;
  661.       p->Value = (byte == F_TRUE);
  662.       break;
  663.  
  664.     case F_PI:
  665.       p->type = TYP_FLT;
  666.       p->Float = PI;
  667.       break;
  668.  
  669.     case F_ROW:
  670.     case F_COL:
  671.       p->type = TYP_INT;
  672.       p->Int = ((byte == F_ROW) ? cur_row : cur_col);
  673.       break;
  674.  
  675.     case F_NOW:
  676.       p->type = TYP_INT;
  677.       p->Int = time ((VOIDSTAR) 0);
  678.       break;
  679.  
  680.       /* Single operand instrs */
  681.     case F_ABS:
  682.     case F_ACOS:
  683.     case F_ASIN:
  684.     case F_ATAN:
  685.     case F_CEIL:
  686.     case F_COS:
  687.     case F_DTR:
  688.     case F_EXP:
  689.     case F_FLOOR:
  690.     case F_INT:
  691.     case F_LOG:
  692.     case F_LOG10:
  693.     case F_RTD:
  694.     case F_SIN:
  695.     case F_SQRT:
  696.     case F_TAN:
  697.       {
  698. #ifdef __STDC__
  699.         double (*funp1) (double);
  700.         funp1 = (double (*)(double)) (f->fn_fun);
  701. #else
  702.         double (*funp1) ();
  703.         funp1 = (double (*)()) (f->fn_fun);
  704. #endif
  705.  
  706.         p->Float = (*funp1) (p->Float);
  707.         if (p->Float != p->Float)
  708.           ERROR (OUT_OF_RANGE);
  709.       }
  710.       break;
  711.  
  712.     case F_CTIME:
  713.       p->type = TYP_STR;
  714.       strptr = ctime ((time_t*) &p->Int);
  715.       p->String = obstack_alloc (&tmp_mem, 25);
  716.       strncpy (p->String, strptr, 24);
  717.       p->String[24] = '\0';
  718.       break;
  719.  
  720.     case NEGATE:
  721.     case F_NEG:
  722.       if (p->type == TYP_ERR)
  723.         break;
  724.       if (p->type == TYP_INT)
  725.         p->Int = -(p->Int);
  726.       else if (p->type == TYP_FLT)
  727.         p->Float = -(p->Float);
  728.       else
  729.         ERROR (NON_NUMBER);
  730.       break;
  731.  
  732.     case F_RND:
  733.       p->Int = (random () % (p->Int)) + 1;
  734.       break;
  735.  
  736.     case NOT:
  737.     case F_NOT:
  738.       p->Value = !(p->Value);
  739.       break;
  740.  
  741.     case F_ISERR:
  742.       p->Value = (p->type == TYP_ERR);
  743.       p->type = TYP_BOL;
  744.       break;
  745.  
  746.     case F_ISNUM:
  747.       if (p->type == TYP_FLT || p->type == TYP_INT)
  748.         p->Value = 1;
  749.       else if (p->type == TYP_STR)
  750.         {
  751.           strptr = p->String;
  752.           (void) astof (&strptr);
  753.           p->Value = (*strptr == '\0');
  754.         }
  755.       else
  756.         p->Value = 0;
  757.       p->type = TYP_BOL;
  758.       break;
  759.  
  760.     case F_ROWS:
  761.     case F_COLS:
  762.       p->type = TYP_INT;
  763.       p->Int = 1 + (byte == F_ROWS ? (p->Rng.hr - p->Rng.lr) : (p->Rng.hc - p->Rng.lc));
  764.       break;
  765.  
  766.       /* Two operand cmds */
  767.     case F_ATAN2:
  768.     case F_HYPOT:
  769.     case POW:
  770.       {
  771. #ifdef __STDC__
  772.         double (*funp2) (double, double);
  773.         funp2 = (double (*)(double, double)) (f->fn_fun);
  774. #else
  775.         double (*funp2) ();
  776.         funp2 = (double (*)()) (f->fn_fun);
  777. #endif
  778.  
  779.         p->Float = (*funp2) (p->Float, (p + 1)->Float);
  780.         if (p->Float != p->Float)
  781.           ERROR (OUT_OF_RANGE);
  782.       }
  783.       break;
  784.  
  785.     case DIFF:
  786.     case DIV:
  787.     case MOD:
  788.     case PROD:
  789.     case SUM:
  790.  
  791.       if (p->type != (p + 1)->type)
  792.         {
  793.           if (p->type == TYP_INT)
  794.         {
  795.           p->type = TYP_FLT;
  796.           p->Float = (double) p->Int;
  797.         }
  798.           if ((p + 1)->type == TYP_INT)
  799.         {
  800.           (p + 1)->type = TYP_FLT;
  801.           (p + 1)->Float = (double) ((p + 1)->Int);
  802.         }
  803.         }
  804.       if (p->type == TYP_INT)
  805.         {
  806.           switch (byte)
  807.         {
  808.         case DIFF:
  809.           I_SUB (p->Int, (p + 1)->Int);
  810.           break;
  811.         case DIV:
  812.           if ((p + 1)->Int == 0)
  813.             ERROR (DIV_ZERO);
  814.           I_DIV (p->Int, (p + 1)->Int);
  815.           break;
  816.         case MOD:
  817.           if ((p + 1)->Int == 0)
  818.             ERROR (DIV_ZERO);
  819.           I_MOD (p->Int, (p + 1)->Int);
  820.           break;
  821.         case PROD:
  822.           I_MUL (p->Int, (p + 1)->Int);
  823.           break;
  824.         case SUM:
  825.           I_ADD (p->Int, (p + 1)->Int);
  826.           break;
  827. #ifdef TEST
  828.         default:
  829.           panic ("Evaluator confused by byte-value %d", byte);
  830. #endif
  831.         }
  832.         }
  833.       else
  834.         {
  835.           switch (byte)
  836.         {
  837.         case DIFF:
  838.           F_SUB (p->Float, (p + 1)->Float);
  839.           break;
  840.         case DIV:
  841.           if ((p + 1)->Float == 0)
  842.             ERROR (DIV_ZERO);
  843.           F_DIV (p->Float, (p + 1)->Float);
  844.           break;
  845.         case MOD:
  846.           if ((p + 1)->Float == 0)
  847.             ERROR (DIV_ZERO);
  848.           F_MOD (p->Float, (p + 1)->Float);
  849.           break;
  850.         case PROD:
  851.           F_MUL (p->Float, (p + 1)->Float);
  852.           break;
  853.         case SUM:
  854.           F_ADD (p->Float, (p + 1)->Float);
  855.           break;
  856. #ifdef TEST
  857.         default:
  858.           panic ("Unknown operation %d", byte);
  859. #endif
  860.         }
  861.         }
  862.       if (overflow)
  863.         ERROR (OUT_OF_RANGE);
  864.       break;
  865.  
  866.     case EQUAL:
  867.     case NOTEQUAL:
  868.  
  869.     case GREATEQ:
  870.     case GREATER:
  871.     case LESS:
  872.     case LESSEQ:
  873.       if (p->type == TYP_ERR)
  874.         break;
  875.       if ((p + 1)->type == TYP_ERR)
  876.         ERROR ((p + 1)->Value);
  877.  
  878.       if (p->type == TYP_BOL || (p + 1)->type == TYP_BOL)
  879.         {
  880.           if (p->type != (p + 1)->type || (byte != EQUAL && byte != NOTEQUAL))
  881.         ERROR (BAD_INPUT);
  882.           if (byte == EQUAL)
  883.         p->Value = p->Value == (p + 1)->Value;
  884.           else
  885.         p->Value = p->Value != (p + 1)->Value;
  886.           break;
  887.         }
  888.       if (p->type != (p + 1)->type)
  889.         {
  890.           if (p->type == 0)
  891.         {
  892.           if ((p + 1)->type == TYP_STR)
  893.             {
  894.               p->type = TYP_STR;
  895.               p->String = "";
  896.             }
  897.           else if ((p + 1)->type == TYP_INT)
  898.             {
  899.               p->type = TYP_INT;
  900.               p->Int = 0;
  901.             }
  902.           else
  903.             {
  904.               p->type = TYP_FLT;
  905.               p->Float = 0.0;
  906.             }
  907.         }
  908.           else if ((p + 1)->type == 0)
  909.         {
  910.           if (p->type == TYP_STR)
  911.             {
  912.               (p + 1)->type = TYP_STR;
  913.               (p + 1)->String = "";
  914.             }
  915.           else if (p->type == TYP_INT)
  916.             {
  917.               (p + 1)->type = TYP_INT;
  918.               (p + 1)->Int = 0;
  919.             }
  920.           else
  921.             {
  922.               (p + 1)->type = TYP_FLT;
  923.               (p + 1)->Float = 0.0;
  924.             }
  925.         }
  926.           else if (p->type == TYP_STR)
  927.         {
  928.           strptr = p->String;
  929.           if ((p + 1)->type == TYP_INT)
  930.             {
  931.               p->type = TYP_INT;
  932.               p->Int = astol (&strptr);
  933.             }
  934.           else
  935.             {
  936.               p->type = TYP_FLT;
  937.               p->Float = astof (&strptr);
  938.             }
  939.           if (*strptr)
  940.             {
  941.               p->type = TYP_BOL;
  942.               p->Value = (byte == NOTEQUAL);
  943.               break;
  944.             }
  945.         }
  946.           else if ((p + 1)->type == TYP_STR)
  947.         {
  948.           strptr = (p + 1)->String;
  949.           if (p->type == TYP_INT)
  950.             (p + 1)->Int = astol (&strptr);
  951.           else
  952.             (p + 1)->Float = astof (&strptr);
  953.           if (*strptr)
  954.             {
  955.               p->type = TYP_BOL;
  956.               p->Value = (byte == NOTEQUAL);
  957.               break;
  958.             }
  959.  
  960.           /* If we get here, one is INT, and the other
  961.                    is FLT  Make them both FLT */
  962.         }
  963.           else if (p->type == TYP_INT)
  964.         {
  965.           p->type = TYP_FLT;
  966.           p->Float = (double) p->Int;
  967.         }
  968.           else
  969.         (p + 1)->Float = (double) (p + 1)->Int;
  970.         }
  971.       if (p->type == TYP_STR)
  972.         tmp = strcmp (p->String, (p + 1)->String);
  973.       else if (p->type == TYP_FLT)
  974.         tmp = (p->Float < (p + 1)->Float) ? -1 : ((p->Float > (p + 1)->Float) ? 1 : 0);
  975.       else if (p->type == TYP_INT)
  976.         tmp = (p->Int < (p + 1)->Int ? -1 : ((p->Int > (p + 1)->Int) ? 1 : 0));
  977.       else if (p->type == 0)
  978.         tmp = 0;
  979.       else
  980.         {
  981.           tmp = 0;
  982.           panic ("Bad type value %d", p->type);
  983.         }
  984.       p->type = TYP_BOL;
  985.       if (tmp < 0)
  986.         p->Value = (byte == NOTEQUAL || byte == LESS || byte == LESSEQ);
  987.       else if (tmp == 0)
  988.         p->Value = (byte == EQUAL || byte == GREATEQ || byte == LESSEQ);
  989.       else
  990.         p->Value = (byte == NOTEQUAL || byte == GREATER || byte == GREATEQ);
  991.       break;
  992.  
  993.     case F_FIXED:
  994.       tmp = (p + 1)->Int;
  995.       if (tmp < -29 || tmp > 29)
  996.         ERROR (OUT_OF_RANGE);
  997.       if (tmp < 0)
  998.         p->Float = rint ((p->Float) / exp10_arr[-tmp]) * exp10_arr[-tmp];
  999.       else
  1000.         p->Float = rint ((p->Float) * exp10_arr[tmp]) / exp10_arr[tmp];
  1001.       break;
  1002.  
  1003.     case F_IFERR:
  1004.       if (p->type == TYP_ERR)
  1005.         *p = *(p + 1);
  1006.       break;
  1007.  
  1008.     case F_INDEX:
  1009.       tmp = (p + 1)->Int - 1;
  1010.       if (tmp < 0)
  1011.         ERROR (OUT_OF_RANGE);
  1012.       lrow = p->Rng.lr;
  1013.       lcol = p->Rng.lc;
  1014.       hrow = p->Rng.hr;
  1015.       hcol = p->Rng.hc;
  1016.       if (lrow != hrow && lcol != hcol)
  1017.         {
  1018.           int dex;
  1019.  
  1020.           dex = 1 + hrow - lrow;
  1021.           if (tmp >= dex * (1 + hcol - lcol))
  1022.         ERROR (OUT_OF_RANGE);
  1023.           crow = tmp % dex;
  1024.           ccol = tmp / dex;
  1025.           lrow += crow;
  1026.           lcol += ccol;
  1027.         }
  1028.       else if (lrow != hrow)
  1029.         {
  1030.           if (tmp > (hrow - lrow))
  1031.         ERROR (OUT_OF_RANGE);
  1032.           lrow += tmp;
  1033.         }
  1034.       else
  1035.         {
  1036.           if (tmp > (hcol - lcol))
  1037.         ERROR (OUT_OF_RANGE);
  1038.           lcol += tmp;
  1039.         }
  1040.       cell_ptr = find_cell (lrow, lcol);
  1041.       PUSH_ANY (cell_ptr);
  1042.       break;
  1043.  
  1044.     case F_INDEX2:
  1045.       crow = (p + 1)->Int - 1;
  1046.       ccol = (p + 2)->Int - 1;
  1047.       lrow = p->Rng.lr;
  1048.       lcol = p->Rng.lc;
  1049.       hrow = p->Rng.hr;
  1050.       hcol = p->Rng.hc;
  1051.       /* This generates warnings if CELLREF is an unsigned type. 
  1052.         * Getting rid of the warning is more trouble than 
  1053.         * it's worth.
  1054.         */
  1055.       if (crow < 0 || ccol < 0 || crow > (hrow - lrow) ||
  1056.           ccol > (hcol - lcol)) 
  1057.         ERROR (OUT_OF_RANGE);
  1058.       cell_ptr = find_cell (lrow + crow, lcol + ccol);
  1059.       PUSH_ANY (cell_ptr);
  1060.       break;
  1061.  
  1062.       /* case F_PRINTF:
  1063.             panic("no printf yet");
  1064.             break; */
  1065.  
  1066.     case CONCAT:
  1067.       strptr = (char *) obstack_alloc (&tmp_mem, strlen (p->String) + strlen ((p + 1)->String) + 1);
  1068.       strcpy (strptr, p->String);
  1069.       strcat (strptr, (p + 1)->String);
  1070.       p->String = strptr;
  1071.       break;
  1072.  
  1073.     case F_ONEOF:
  1074.       if (numarg < 2)
  1075.         ERROR (NO_VALUES);
  1076.       --numarg;
  1077.       tmp = p->Int;
  1078.       if (tmp < 1 || tmp > numarg)
  1079.         ERROR (OUT_OF_RANGE);
  1080.       /* Can never happen? */
  1081.       TO_ANY (p + tmp);
  1082.       p[0] = p[tmp];
  1083.       break;
  1084.  
  1085.     case F_FILE:
  1086.       {
  1087.         FILE *fp;
  1088.         char buf[128];
  1089.         int num;
  1090.  
  1091.         if (numarg < 1)
  1092.           ERROR (NO_VALUES);
  1093.         fp = fopen (p->String, "r");
  1094.         if (!fp)
  1095.           ERROR (BAD_INPUT);
  1096.         switch (numarg)
  1097.           {
  1098.           case 2:
  1099.         fseek (fp, (p + 1)->Int, 0);
  1100.         /* Fallthrough */
  1101.  
  1102.           case 1:
  1103.         while ((num = fread (buf, sizeof (char), sizeof (buf), fp)) > 0)
  1104.             (void) obstack_grow (&tmp_mem, buf, num);
  1105.         break;
  1106.  
  1107.           case 3:
  1108.         fseek (fp, (p + 1)->Int, 0);
  1109.         for (;;)
  1110.           {
  1111.             num = ((p + 2)->Int < sizeof (buf)) ? (p + 2)->Int : sizeof (buf);
  1112.             (p + 2)->Int -= num;
  1113.             num = fread (buf, sizeof (char), num, fp);
  1114.             (void) obstack_grow (&tmp_mem, buf, num);
  1115.             if (num == 0 || (p + 2)->Int == 0)
  1116.               break;
  1117.           }
  1118.         break;
  1119.  
  1120.           default:
  1121.         ERROR (BAD_INPUT);
  1122.           }
  1123.         fclose (fp);
  1124.         (void) obstack_1grow (&tmp_mem, 0);
  1125.         p->String = obstack_finish (&tmp_mem);
  1126.         break;
  1127.       }
  1128.  
  1129.     case AREA_SUM:
  1130.     case AREA_PROD:
  1131.     case AREA_AVG:
  1132.     case AREA_STD:
  1133.     case AREA_MAX:
  1134.     case AREA_MIN:
  1135.     case AREA_CNT:
  1136.     case AREA_VAR:
  1137.       tmp = deal_area (byte, numarg, p);
  1138.       if (tmp)
  1139.         ERROR (tmp);
  1140.       break;
  1141.  
  1142.       /* This is now a fallthrough for all the USRmumble codes */
  1143.     case USR1:
  1144.     default:
  1145.       if ((f->fn_argn & X_ARGS) == X_AN)
  1146.         {
  1147. #ifdef __STDC__
  1148.           void (*funp) (int, struct value *);
  1149.           funp = (void (*)(int, struct value *)) f->fn_fun;
  1150. #else
  1151.           void (*funp) ();
  1152.           funp = (void (*)()) f->fn_fun;
  1153. #endif
  1154.           (*funp) (numarg, p);
  1155.         }
  1156.       else
  1157.         {
  1158. #ifdef __STDC__
  1159.           void (*funp) (struct value *);
  1160.           funp = (void (*)(struct value *)) f->fn_fun;
  1161. #else
  1162.           void (*funp) ();
  1163.           funp = (void (*)()) f->fn_fun;
  1164. #endif
  1165.           (*funp) (p);
  1166.         }
  1167.       break;
  1168.  
  1169.       /* #ifdef TEST
  1170.         default:
  1171.             panic("Unknown byte-value %d",byte);
  1172.             break;
  1173. #endif */
  1174.     }
  1175.       /* Goto next-byte is the equiv of a multi-level break, which
  1176.            C doesn't allow. */
  1177.     next_byte:
  1178.       ;
  1179.     }
  1180. #ifdef TEST
  1181.   if (curstack != 1)
  1182.     io_error_msg ("%d values on stack", curstack);
  1183. #endif
  1184.   return stack;
  1185. }
  1186.  
  1187. /* These helper functions were split out so that eval_expression would compile
  1188.    under Turbo C 2.0 on my PC.
  1189.  */
  1190.  
  1191.  
  1192. static int cnt_flt;
  1193. static int cnt_int;
  1194.  
  1195. static long int_tmp;
  1196. static double flt_tmp;
  1197.  
  1198. static long sqr_int_tmp;    /* for AREA_STD */
  1199. static double sqr_flt_tmp;
  1200.  
  1201. static unsigned char area_cmd;
  1202.  
  1203. static int
  1204. deal_area (cmd, num_args, p)
  1205.      unsigned char cmd;
  1206.      unsigned char num_args;
  1207.      struct value *p;
  1208. {
  1209.   double flt_cnt_flt;
  1210.   CELL *cell_ptr;
  1211.   char *strptr;
  1212.  
  1213.   area_cmd = cmd;
  1214.   cnt_flt = 0;
  1215.   cnt_int = 0;
  1216.   for (; num_args--;)
  1217.     {
  1218.       switch (p[num_args].type)
  1219.     {
  1220.     case TYP_INT:
  1221.       add_int (p[num_args].Int);
  1222.       break;
  1223.  
  1224.     case TYP_FLT:
  1225.       add_flt (p[num_args].Float);
  1226.       break;
  1227.  
  1228.     case TYP_STR:
  1229.       strptr = p[num_args].String;
  1230.       flt_cnt_flt = astof (&strptr);
  1231.       if (*strptr)
  1232.         return NON_NUMBER;
  1233.       add_flt (flt_cnt_flt);
  1234.       break;
  1235.  
  1236.     case TYP_RNG:
  1237.       find_cells_in_range (&(p[num_args].Rng));
  1238.       while (cell_ptr = next_cell_in_range ())
  1239.         {
  1240.           if (GET_TYP (cell_ptr) == TYP_FLT)
  1241.         add_flt (cell_ptr->cell_flt);
  1242.           else if (GET_TYP (cell_ptr) == TYP_INT)
  1243.         add_int (cell_ptr->cell_int);
  1244.           else if (GET_TYP (cell_ptr) == TYP_STR)
  1245.         {
  1246.           strptr = cell_ptr->cell_str;
  1247.           flt_cnt_flt = astof (&strptr);
  1248.           if (!*strptr)
  1249.             add_flt (flt_cnt_flt);
  1250.         }
  1251.         }
  1252.       break;
  1253.  
  1254.     case 0:
  1255.       break;
  1256.  
  1257.     case TYP_ERR:
  1258.       return p[num_args].Value;
  1259.  
  1260.     default:
  1261.       return NON_NUMBER;
  1262.     }
  1263.     }
  1264.   if (!cnt_flt && !cnt_int && area_cmd != AREA_CNT)
  1265.     return NO_VALUES;
  1266.  
  1267.   switch (area_cmd)
  1268.     {
  1269.     case AREA_SUM:
  1270.       if (cnt_flt && cnt_int)
  1271.     {
  1272.       flt_tmp += (double) int_tmp;
  1273.       cnt_int = 0;
  1274.     }
  1275.       break;
  1276.     case AREA_PROD:
  1277.       if (cnt_flt && cnt_int)
  1278.     {
  1279.       flt_tmp *= (double) int_tmp;
  1280.       cnt_int = 0;
  1281.     }
  1282.       break;
  1283.     case AREA_AVG:
  1284.       if (cnt_flt && cnt_int)
  1285.     {
  1286.       flt_tmp += (double) int_tmp;
  1287.       flt_tmp /= (double) ((cnt_flt + cnt_int));
  1288.       cnt_int = 0;
  1289.     }
  1290.       else if (cnt_flt)
  1291.     flt_tmp /= (double) cnt_flt;
  1292.       else
  1293.     {
  1294.       flt_tmp = (double) int_tmp / (double) cnt_int;
  1295.       cnt_int = 0;
  1296.     }
  1297.       break;
  1298.     case AREA_STD:
  1299.       if (cnt_int && cnt_flt)
  1300.     {
  1301.       flt_tmp += (double) int_tmp;
  1302.       sqr_flt_tmp += (double) sqr_int_tmp;
  1303.       cnt_flt += cnt_int;
  1304.       cnt_int = 0;
  1305.     }
  1306.       else if (cnt_int)
  1307.     {
  1308.       flt_tmp = (double) int_tmp;
  1309.       sqr_flt_tmp = (double) sqr_int_tmp;
  1310.       cnt_flt = cnt_int;
  1311.       cnt_int = 0;
  1312.     }
  1313.       flt_cnt_flt = (double) cnt_flt;
  1314.       flt_tmp = sqrt (((flt_cnt_flt * sqr_flt_tmp) -
  1315.                (flt_tmp * flt_tmp)) /
  1316.               (flt_cnt_flt * (flt_cnt_flt - 1)));
  1317.       break;
  1318.     case AREA_VAR:
  1319.       if (cnt_int && cnt_flt)
  1320.     {
  1321.       flt_tmp += (double) int_tmp;
  1322.       sqr_flt_tmp += (double) sqr_int_tmp;
  1323.       cnt_flt += cnt_int;
  1324.       cnt_int = 0;
  1325.     }
  1326.       else if (cnt_int)
  1327.     {
  1328.       flt_tmp = (double) int_tmp;
  1329.       sqr_flt_tmp = (double) sqr_int_tmp;
  1330.       cnt_flt = cnt_int;
  1331.       cnt_int = 0;
  1332.     }
  1333.       flt_cnt_flt = (double) cnt_flt;
  1334.       flt_tmp = ((flt_cnt_flt * sqr_flt_tmp) -
  1335.          (flt_tmp * flt_tmp)) /
  1336.     (flt_cnt_flt * flt_cnt_flt);
  1337.       break;
  1338.  
  1339.     case AREA_MAX:
  1340.       if (cnt_flt && cnt_int && flt_tmp > (double) int_tmp)
  1341.     cnt_int = 0;
  1342.       break;
  1343.  
  1344.     case AREA_MIN:
  1345.       if (cnt_flt && cnt_int && flt_tmp < (double) int_tmp)
  1346.     cnt_int = 0;
  1347.       break;
  1348.  
  1349.     case AREA_CNT:
  1350.       int_tmp = cnt_int + cnt_flt;
  1351.       cnt_int = 1;
  1352.       break;
  1353.  
  1354. #ifdef TEST
  1355.     default:
  1356.       panic ("Unknown AREA command %d", area_cmd);
  1357. #endif
  1358.     }
  1359.   if (cnt_int)
  1360.     {
  1361.       p->type = TYP_INT;
  1362.       p->Int = int_tmp;
  1363.     }
  1364.   else
  1365.     {
  1366.       p->type = TYP_FLT;
  1367.       p->Float = flt_tmp;
  1368.     }
  1369.   return 0;
  1370. }
  1371.  
  1372. static void
  1373. add_flt (value)
  1374.      double value;
  1375. {
  1376.   if (cnt_flt++ == 0)
  1377.     {
  1378.       flt_tmp = value;
  1379.       sqr_flt_tmp = value * value;
  1380.       return;
  1381.     }
  1382.  
  1383.   switch (area_cmd)
  1384.     {
  1385.     case AREA_STD:
  1386.     case AREA_VAR:
  1387.       sqr_flt_tmp += value * value;
  1388.       /* Fall through */
  1389.     case AREA_SUM:
  1390.     case AREA_AVG:
  1391.       flt_tmp += value;
  1392.       return;
  1393.     case AREA_PROD:
  1394.       flt_tmp *= value;
  1395.       return;
  1396.     case AREA_MAX:
  1397.       if (flt_tmp < value)
  1398.     flt_tmp = value;
  1399.       return;
  1400.     case AREA_MIN:
  1401.       if (flt_tmp > value)
  1402.     flt_tmp = value;
  1403.       return;
  1404.     case AREA_CNT:
  1405.       return;
  1406. #ifdef TEST
  1407.     default:
  1408.       panic ("Unknown area command %d in add_flt(%g)", area_cmd, value);
  1409. #endif
  1410.     }
  1411. }
  1412.  
  1413. static void
  1414. add_int (value)
  1415.      long value;
  1416. {
  1417.   if (cnt_int++ == 0)
  1418.     {
  1419.       int_tmp = value;
  1420.       sqr_int_tmp = value * value;
  1421.       return;
  1422.     }
  1423.  
  1424.   switch (area_cmd)
  1425.     {
  1426.     case AREA_STD:
  1427.     case AREA_VAR:
  1428.       sqr_int_tmp += value * value;
  1429.       /* Fall through */
  1430.     case AREA_SUM:
  1431.     case AREA_AVG:
  1432.       int_tmp += value;
  1433.       return;
  1434.     case AREA_PROD:
  1435.       int_tmp *= value;
  1436.       return;
  1437.     case AREA_MAX:
  1438.       if (int_tmp < value)
  1439.     int_tmp = value;
  1440.       return;
  1441.     case AREA_MIN:
  1442.       if (int_tmp > value)
  1443.     int_tmp = value;
  1444.       return;
  1445.     case AREA_CNT:
  1446.       return;
  1447. #ifdef TEST
  1448.     default:
  1449.       panic ("Unknown Area command %d in add_int(%ld)", area_cmd, value);
  1450. #endif
  1451.     }
  1452. }
  1453.  
  1454. #ifdef __STDC__
  1455. double
  1456. dtr (double x)
  1457. #else
  1458. double
  1459. dtr (x)
  1460.      double x;
  1461. #endif
  1462. {
  1463.   return x * (PI / (double) 180.0);
  1464. }
  1465.  
  1466. #ifdef __STDC__
  1467. double
  1468. rtd (double x)
  1469. #else
  1470. double
  1471. rtd (x)
  1472.      double x;
  1473. #endif
  1474. {
  1475.   return x * (180.0 / (double) PI);
  1476. }
  1477.  
  1478. #ifdef __STDC__
  1479. double
  1480. to_int (double x)
  1481. #else
  1482. double
  1483. to_int (x)
  1484.      double x;
  1485. #endif
  1486. {
  1487.   return (x < 0 ? ceil (x) : floor (x));
  1488. }
  1489.  
  1490. /* Various methods of dealing with arithmatic overflow.  They don't work well.
  1491.    Someone should really convince this thing to properly deal with it.
  1492.  */
  1493. #ifdef __TURBOC__
  1494. int
  1495. matherr (exc)
  1496.      struct exception *exc;
  1497. {
  1498.   stack[curstack].type = TYP_ERR;
  1499.   stack[curstack].Value = BAD_INPUT;
  1500.   write (2, "MATHERR\n", 8);
  1501.   return 1;
  1502. }
  1503.  
  1504. #endif
  1505.  
  1506. #ifndef __TURBOC__
  1507. RETSIGTYPE
  1508. math_sig (sig)
  1509.      int sig;
  1510. {
  1511.   stack[curstack].type = TYP_ERR;
  1512.   stack[curstack].Value = BAD_INPUT;
  1513. }
  1514.  
  1515. #endif
  1516.  
  1517. /* Here's the entry point for this module. */
  1518. void
  1519. update_cell (cell)
  1520.      CELL *cell;
  1521. {
  1522.   struct value *new;
  1523.   int new_val;
  1524.  
  1525. #ifdef TEST
  1526.   extern int debug;
  1527.  
  1528.   if (cell->cell_cycle == current_cycle && (debug & 01))
  1529.     {
  1530.       io_error_msg ("Cycle detected at %s (%d)", cell_name (cur_row, cur_col), current_cycle);
  1531.       /* return; */
  1532.     }
  1533.   else if (debug & 02)
  1534.     io_error_msg ("Update %s", cell_name (cur_row, cur_col));
  1535. #endif
  1536.   new = eval_expression (cell->cell_formula);
  1537.   if (!new)
  1538.     {
  1539.       push_refs (cell->cell_refs_from);
  1540.       return;
  1541.     }
  1542.   cell->cell_cycle = current_cycle;
  1543.  
  1544.   if (new->type != GET_TYP (cell))
  1545.     {
  1546.       if (GET_TYP (cell) == TYP_STR)
  1547.     free (cell->cell_str);
  1548.       SET_TYP (cell, new->type);
  1549.       new_val = 1;
  1550.       if (new->type == TYP_STR)
  1551.     new->String = strdup (new->String);
  1552.     }
  1553.   else
  1554.     switch (new->type)
  1555.       {
  1556.       case 0:
  1557.     new_val = 0;
  1558.     break;
  1559.       case TYP_FLT:
  1560.     new_val = new->Float != cell->cell_flt;
  1561.     break;
  1562.       case TYP_INT:
  1563.     new_val = new->Int != cell->cell_int;
  1564.     break;
  1565.       case TYP_STR:
  1566.     new_val = strcmp (new->String, cell->cell_str);
  1567.     if (new_val)
  1568.       {
  1569.         free (cell->cell_str);
  1570.         new->String = strdup (new->String);
  1571.       }
  1572.     break;
  1573.       case TYP_BOL:
  1574.     new_val = new->Value != cell->cell_bol;
  1575.     break;
  1576.       case TYP_ERR:
  1577.     new_val = new->Value != cell->cell_err;
  1578.     break;
  1579. #ifdef TEST
  1580.       default:
  1581.     new_val = 0;
  1582.     panic ("Unknown type %d in update_cell", new->type);
  1583. #endif
  1584.       }
  1585.   if (new_val)
  1586.     {
  1587.       cell->c_z = new->x;
  1588.       push_refs (cell->cell_refs_from);
  1589.     }
  1590.   (void) obstack_free (&tmp_mem, tmp_mem_start);
  1591. }
  1592.  
  1593. int
  1594. fls (num)
  1595.      long num;
  1596. {
  1597.   int ret = 1;
  1598.  
  1599.   if (!num)
  1600.     return 0;
  1601.   if (num < 0)
  1602.     num = -num;
  1603.   if (num & 0xffff0000)
  1604.     {
  1605.       ret += 16;
  1606.       num = (num >> 16) & 0xffff;
  1607.     }
  1608.   if (num & 0xff00)
  1609.     {
  1610.       ret += 8;
  1611.       num >>= 8;
  1612.     }
  1613.   if (num & 0xf0)
  1614.     {
  1615.       ret += 4;
  1616.       num >>= 4;
  1617.     }
  1618.   if (num & 0x0c)
  1619.     {
  1620.       ret += 2;
  1621.       num >>= 2;
  1622.     }
  1623.   if (num & 2)
  1624.     ret++;
  1625.   return ret;
  1626. }
  1627.  
  1628. #ifdef SMALLEVAL
  1629. int
  1630. __to_flt (p)
  1631.      struct value *p;
  1632. {
  1633.   char *strptr;
  1634.  
  1635.   switch (p->type)
  1636.     {
  1637.     case 0:
  1638.       p->type = TYP_FLT;
  1639.       p->Float = 0;
  1640.       /* Fallthrough */
  1641.     case TYP_FLT:
  1642.       return 0;
  1643.     case TYP_INT:
  1644.       p->Float = (double) p->Int;
  1645.       p->type = TYP_FLT;
  1646.       return 0;
  1647.     case TYP_STR:
  1648.       p->type = TYP_FLT;
  1649.       strptr = p->String;
  1650.       p->Float = astof (&strptr);
  1651.       if (*strptr)
  1652.     return NON_NUMBER;
  1653.       return 0;
  1654.     case TYP_ERR:
  1655.       return p->Value;
  1656.     default:
  1657.       return NON_NUMBER;
  1658.     }
  1659. }
  1660.  
  1661. int
  1662. __to_int (p)
  1663.      struct value *p;
  1664. {
  1665.   char *strptr;
  1666.  
  1667.   switch (p->type)
  1668.     {
  1669.     case 0:
  1670.       p->type = TYP_INT;
  1671.       p->Int = 0;
  1672.     case TYP_INT:
  1673.       return 0;
  1674.     case TYP_FLT:
  1675.       p->type = TYP_INT;
  1676.       p->Int = (long) p->Float;
  1677.       return 0;
  1678.     case TYP_STR:
  1679.       p->type = TYP_INT;
  1680.       strptr = p->String;
  1681.       p->Int = astol (&strptr);
  1682.       if (*strptr)
  1683.     return NON_NUMBER;
  1684.       return 0;
  1685.     case TYP_ERR:
  1686.       return p->Value;
  1687.     default:
  1688.       return NON_NUMBER;
  1689.     }
  1690. }
  1691.  
  1692. int
  1693. __to_num (p)
  1694.      struct value *p;
  1695. {
  1696.   char *strptr;
  1697.  
  1698.   switch (p->type)
  1699.     {
  1700.     case 0:
  1701.       p->type = TYP_INT;
  1702.       p->Int = 0;
  1703.       return 0;
  1704.     case TYP_FLT:
  1705.     case TYP_INT:
  1706.       return 0;
  1707.     case TYP_STR:
  1708.       p->type = TYP_FLT;
  1709.       strptr = p->String;
  1710.       p->Float = astof (&strptr);
  1711.       if (*strptr)
  1712.     return NON_NUMBER;
  1713.       return 0;
  1714.     case TYP_ERR:
  1715.       return p->Value;
  1716.     default:
  1717.       return NON_NUMBER;
  1718.     }
  1719. }
  1720.  
  1721. int
  1722. __to_str (p)
  1723.      struct value *p;
  1724. {
  1725.   char *strptr;
  1726.  
  1727.   switch (p->type)
  1728.     {
  1729.     case 0:
  1730.       p->type = TYP_STR;
  1731.       p->String = obstack_alloc (&tmp_mem, 1);
  1732.       p->String[0] = '\0';
  1733.       return 0;
  1734.  
  1735.     case TYP_STR:
  1736.       return 0;
  1737.  
  1738.     case TYP_INT:
  1739.       p->type = TYP_STR;
  1740.       strptr = obstack_alloc (&tmp_mem, 30);
  1741.       sprintf (strptr, "%ld", p->Int);
  1742.       p->String = strptr;
  1743.       return 0;
  1744.  
  1745.     case TYP_FLT:
  1746.       p->type = TYP_STR;
  1747.       strptr = flt_to_str (p->Float);
  1748.       (void) obstack_grow (&tmp_mem, strptr, strlen (strptr) + 1);
  1749.       p->String = obstack_finish (&tmp_mem);
  1750.       return 0;
  1751.  
  1752.     case TYP_ERR:
  1753.       return p->Value;
  1754.  
  1755.     default:
  1756.       return NON_STRING;
  1757.     }
  1758. }
  1759.  
  1760. int
  1761. __to_bol (p)
  1762.      struct value *p;
  1763. {
  1764.   switch (p->type)
  1765.     {
  1766.     case TYP_BOL:
  1767.       return 0;
  1768.     case TYP_ERR:
  1769.       return p->Value;
  1770.     default:
  1771.       return NON_BOOL;
  1772.     }
  1773. }
  1774.  
  1775. int
  1776. __to_rng (p)
  1777.      struct value *p;
  1778. {
  1779.   switch (p->type)
  1780.     {
  1781.     case TYP_RNG:
  1782.       return 0;
  1783.     case TYP_ERR:
  1784.       return p->Value;
  1785.     default:
  1786.       return NON_BOOL;
  1787.     }
  1788. }
  1789.  
  1790. #endif
  1791.